package indi.zhifa.study2025.commondata.config;

import cn.hutool.core.io.FileUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.TransportUtils;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.yaml.snakeyaml.Yaml;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;


@Data
public class ElasticSearchClientProvider {

    private EsClientConfig esClientConfig;

    private RestClientBuilder builder;

    public ElasticSearchClientProvider() {
        try{
            init();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public void init() throws IOException {

        Yaml yaml = new Yaml();
        try (InputStream inputStream = FileUtil.class.getClassLoader().getResourceAsStream("el-config.yml")) {
            if (inputStream == null) {
                throw new IllegalArgumentException("File not found: el-config.yml");
            }
            esClientConfig = yaml.loadAs(inputStream, EsClientConfig.class);
        } catch (Exception e) {
            throw new RuntimeException("Failed to load YAML file", e);
        }

        SSLContext sslContext;
        try (InputStream inputStream = FileUtil.class.getClassLoader().getResourceAsStream("http_ca.crt")){
            sslContext = TransportUtils.sslContextFromHttpCaCrt(inputStream);
        }catch (Exception e) {
            throw new RuntimeException("Failed to load http_ca.crt", e);
        }

        builder = RestClient.builder(
                        new HttpHost(esClientConfig.getHost(), esClientConfig.getPort(), "https") // 替换为你的Elasticsearch地址
                ).setDefaultHeaders(new Header[]{
                        new BasicHeader("Authorization", "ApiKey " + esClientConfig.getApiKey())
                })
                .setFailureListener(new RestClient.FailureListener(){
                    @Override
                    public void onFailure(Node node) {
                        super.onFailure(node);
                    }
                }).setHttpClientConfigCallback(hc->
                   hc.setSSLContext(sslContext)
                );
    }


    public ElasticsearchClient get(){
        RestClient restClient = builder.build();
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());
        ElasticsearchClient esClient = new ElasticsearchClient(transport);
        return esClient;
    }

    public static ElasticSearchClientProvider getInstance(){
        return Holder.INSTANCE;
    }

    private static class Holder {
        private static final ElasticSearchClientProvider INSTANCE = new ElasticSearchClientProvider();
    }

}
